package com.nicelee.http.core;

import com.myk.game.gobangchess.constants.AppConfig;
import com.myk.game.gobangchess.utils.PathUtils;
import com.nicelee.config.model.Config;
import com.nicelee.http.core.runnable.SocketDealer;
import com.nicelee.http.core.runnable.SocketMonitor;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FileServer {

    //Configs
    int mode;
    int portServerListening;
    String sourceLocation;
    long socketTimeout;

    boolean isRun = true;
    public static ExecutorService httpThreadPool;
    public static ExecutorService httpProxyThreadPool;
    ServerSocket serverSocket;

    public static void asyncStart() {
        new Thread(() -> {
            FileServer fs = new FileServer();
            fs.startServer();
        }).start();
    }

    public FileServer() {
        this.portServerListening = Integer.parseInt(AppConfig.FILE_SERVER_PORT);
        httpThreadPool = Executors.newFixedThreadPool(30);
        httpProxyThreadPool = Executors.newFixedThreadPool(30);
        this.sourceLocation = PathUtils.getRootPath();
        this.socketTimeout = 120000;
        this.mode = Config.MODE_FILE_HTTP_SERVER;
    }

    /**
     * 关闭服务器
     */
    public void stopServer() {
        try {
            serverSocket.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("正在关闭文件服务器... ");
    }

    /**
     * 打开服务器
     */
    public void startServer() {
        Socket socket = null;
        System.out.println("------文件下载服务启动，监听" + portServerListening + "端口------");
        try {
            serverSocket = new ServerSocket(portServerListening);
            //serverSocket.setSoTimeout(300000);
            //开启Socket监控进程, 时间长于socketTimeout的将会被打断
            SocketMonitor monitor = new SocketMonitor(socketTimeout);
            Thread th = new Thread(monitor);
            th.start();
            while (isRun) {
                try {
                    socket = serverSocket.accept();
                }
                catch (SocketTimeoutException e) {
                    continue;
                }
                catch (SocketException e) {
                    break;
                }
                System.out.println("收到文件下载请求 " + socket.getInetAddress() + ":" + socket.getPort());
                SocketDealer dealer = new SocketDealer(socket, monitor, sourceLocation, mode);
                httpThreadPool.execute(dealer);
                //monitor.put(socket); 改为在线程里面刷新时间(每次Http Request刷新一遍)
            }
            httpThreadPool.shutdownNow();
            th.interrupt();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if (socket != null) {
                try {
                    socket.close();
                }
                catch (IOException ignored) {
                }
            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                }
                catch (IOException ignored) {
                }
            }
        }
        System.out.println("文件服务器已经关闭... ");
    }
}
